package dev.ideas.funkyj.sequence;

import dev.ideas.funkyj.function.F;
import org.junit.Assert;
import org.junit.Test;

import static dev.ideas.funkyj.sequence.Sequence.from;
import static dev.ideas.funkyj.support.PredicateSupport.$;

/**
 */
public class $Notation {

    @Test public void t1() {
        final Person person = new Person("person1", 30, new Address("street1", 10));

        Assert.assertEquals(from(person).where($("street").of($("address")).is("street1")).first(), person);
    }

    @Test public void t2() {
        final Person person = new Person("person1", 30, new Address("street1", 10));

        Assert.assertEquals(from(person).where($("address.street").is("street1")).first(), person);

    }

    //
    public static class Person {
        private String name;
        private Integer age;
        private Address address;

        public Person(String name, Integer age, Address address) { this.name = name; this.age = age; this.address = address; }

        //
        public static final F<Person, String> $name = new F<Person, String>() {
            @Override public String apply(Person person) { return person.name; }
        };
        public static final F<Person, Integer> $age = new F<Person, Integer>() {
            @Override public Integer apply(Person person) { return person.age; }
        };
        public static final F<Person, Address> $address = new F<Person, Address>() {
            @Override public Address apply(Person person) { return person.address; }
        };
    }

    //
    public static class Address {
        private String street;
        private int number;

        public Address(String street, int number) { this.street = street; this.number = number; }

        //
        public static final F<Address, String> $street = new F<Address, String>() {
            public String apply(Address address) { return address.street; }
        };
        public static final F<Address, Integer> $number = new F<Address, Integer>() {
            public Integer apply(Address address) { return address.number; }
        };
    }
}
